#include "protocol.hpp"
#include "Socket.hpp"
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include <unistd.h>

using namespace Protocol;

int main(int argc, char* argv[])
{
    if(argc != 3){
        std::cout << "Usage : " << argv[0] << " serverip serverport" << std::endl;
        return 1;
    }

    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    Net_Work::Socket* conn = new Net_Work::TcpSocket();
    if(!conn->BuildConnectSocketMethod(serverip, serverport))
    {
        std::cerr << "connect " << serverip << ":" << serverport << " failed" << std::endl;
    }
    std::cout << "connect " << serverip << ":" << serverport << " success" << std::endl;
    
    std::unique_ptr<Factory> factory = std::make_unique<Factory>();
    srand(time(nullptr)^getpid());
    const std::string opers = "+-*/%^=&";
    while(true)
    {
        int x =rand()%100;
        usleep(rand() % 7777);
        int y = rand()%100;
        char oper = opers[rand()%opers.size()];
        std::cout << oper <<std::endl;
        std::shared_ptr<Request> req = factory->BuildRequest(x, y, oper);
        
        std::string requeststr;
        req->Serialize(&requeststr);//对请求序列化 e        g.struct -> string :x + y
        std::cout << requeststr << std::endl;
        //
        std::string teststr = requeststr;
        teststr += " = ";//eg. x + y = 
        
        //  x op y -> len\nx op y\n
        requeststr = Encode(requeststr);
        printf("diary\n");
        std::cout<< requeststr << std::endl;
        
        //发送请求
        conn->Send(requeststr);
        
        std::string responsestr;// len\n result code\n  
        while(true)
        {
            
            if(!conn->Recv(&responsestr, 1024))break;
            
            std::string response;//result code
            if(!Decode(responsestr, &response)){
                continue;
            }
            
            auto resp = factory->BuildResponse();
            resp->DeSerialize(response);
            // 8. 得到了计算结果，而且是一个结构化的数据
            std::cout << teststr << resp->GetResult() << "[" << resp->GetCode() << "]" << std::endl;
            break;
        }
        sleep(1);
    }
    conn->CloseSockfd();
    return 0;
}